package com.lzh.runke.core.web_base;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lzh.runke.core.web_base.constant.DateConstant;
import com.lzh.runke.core.web_base.helper.BeanHelper;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.io.Serializable;
import java.util.Date;
import java.util.Map;

/**
 * 返回结果
 *
 * @author xie
 */
@Getter
@Setter
@SuperBuilder
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 3296088007673260597L;

    /**
     * true=成功, false=失败. 默认为true
     */
    @Builder.Default
    protected Boolean success = true;

    /**
     * 错误提示, 成功时不需要返回
     */
    protected String message;

    /**
     * 总记录数, 仅分页时需要
     */
    protected Long total;

    /**
     * 数据
     */
    protected T data;

    /**
     * 时间戳 默认返回当前时间
     */
    @JsonFormat(pattern = DateConstant.FMT_YMDHMS)
    protected Date time;

    public Date getTime() {
        return new Date();
    }

    /**
     * 额外的信息
     */
    private Map<String, Object> extra;

    public boolean succeed() {
        return BooleanUtils.isTrue(this.success);
    }

    public boolean failed() {
        return BooleanUtils.isNotTrue(this.success);
    }

    //Void 和 void 区别?
    public static Result<Void> successVoidResult() {
        return Result.<Void>builder().success(true).build();
    }

    public static Result<Void> failureVoidResult(String message) {
        return Result.<Void>builder().success(false).message(message).build();
    }

    /**
     * 返回data为Void的成功结果的快捷方法
     * @return Result<Void>
     */
    public static Result<Void> successResult() {
        return successResult(null);
    }

    /**
     * 返回成功结果的快捷方法
     * @return Result<Void>
     */
    public static <T> Result<T> successResult(T data) {
        return Result.<T>builder().success(true).data(data).build();
    }

    /**
     * 返回失败结果的快捷方法
     * @return Result<T>
     */
    public static <T> Result<T> failureResult(String message) {
        return Result.<T>builder().success(false).message(message).build();
    }

    @Override
    public String toString() {
        ObjectMapper om = BeanHelper.getBeanIfAbsent(ObjectMapper.class);
        if (null == om) {
            return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
        }
        try {
            return om.writeValueAsString(this);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return super.toString();
    }
}
